package org.csu.forum.controller;

import org.csu.forum.common.CommonResponse;
import org.csu.forum.domain.PO.Files;
import org.csu.forum.domain.PO.Post;
import org.csu.forum.domain.PO.ReplyContent;
import org.csu.forum.domain.PO.Titlepost;
import org.csu.forum.domain.VO.FollowPostVO;
import org.csu.forum.service.AccountService;
import org.csu.forum.service.PostManageService;
import org.csu.forum.service.SectionService;
import org.csu.forum.utils.TokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.*;

@Controller
public class PostManageController{
    @Autowired
    PostManageService postManageService;

    @Autowired
    SectionService sectionService;

    @Autowired
    AccountService accountService;

    @Autowired
    HttpServletRequest httpServletRequest;

    @PostMapping("/users/{userid}/titleposts")
    @ResponseBody
    public CommonResponse<Map<String,String>> postTitleposts(@PathVariable int userid , @RequestBody Titlepost titlepost){
        if(verifyUserid(userid)){
            return CommonResponse.createForError("不能以其他用户身份发送贴子");
        }
        Map<String,String>map = new HashMap<>();
        postManageService.addTitlepost(titlepost,userid);
        map.put("content",titlepost.getContent());
        map.put("zoneid",Integer.toString(titlepost.getZoneid()));
        map.put("isvote",Boolean.toString(titlepost.getIsvote()));
        return CommonResponse.createForSuccess(map,"发布主题贴成功");
    }

    @PostMapping("/users/{userid}/posts")
    @ResponseBody
    public CommonResponse<Map<String,String>> postPosts(@RequestBody Post post , @RequestParam int followpost_floor ,@RequestParam int titlepost_id , @PathVariable int userid){
        if(verifyUserid(userid)){
            return CommonResponse.createForError("不能以其他用户身份发送贴子");
        }
        Map<String,String>map = new HashMap<>();
        if(post.getFileid() == 0){
            post.setFileid(-1);
        }
        int postId = postManageService.addPost(post, userid,followpost_floor,titlepost_id);
        map.put("postId",Integer.toString(postId));
        map.put("content",post.getContent());
        map.put("zoneId",Integer.toString(post.getZoneid()));
        map.put("sectionId",Integer.toString(sectionService.getSectionIdByZoneId(post.getZoneid())));

        if(post.getFileid() != -1) {
            Files files = sectionService.getFileSrc(post.getFileid());
            map.put("fileId", Integer.toString(post.getFileid()));
            map.put("fileDescription", files.getFileDescription());
            map.put("filesrc", files.getFilesrc());
        }

        return CommonResponse.createForSuccess(map,"发布贴子成功");
    }

    @GetMapping("/zones/{zoneid}/titleposts")
    @ResponseBody
    public CommonResponse<List<Titlepost>> getTitlepostListByZoneID(@PathVariable int zoneid){
        if(postManageService.getTitlepostList(zoneid) != null){
            return CommonResponse.createForSuccess(postManageService.getTitlepostList(zoneid),"获取该分区主题帖成功");
        }
        return CommonResponse.createForError("该分区无主题帖");
    }

    @GetMapping("/titleposts/{titlepost_id}/posts")
    @ResponseBody
    public CommonResponse<List<FollowPostVO>> getFollowPostVOList(@PathVariable int titlepost_id){
        if(postManageService.getFollowPostVOList(titlepost_id) != null){
            return CommonResponse.createForSuccess(postManageService.getFollowPostVOList(titlepost_id),"获取所有跟贴成功");
        }
        return CommonResponse.createForError("获取所有跟贴失败");
    }

    @PostMapping("/posts/{post_id}/replies")
    @ResponseBody
    public CommonResponse<Map<String,String>> replyPost(@RequestBody ReplyContent replyContent){
        int userid = TokenUtils.getClaimByToken(httpServletRequest.getHeader("token"),"userid");
        if(userid == 0){
            return CommonResponse.createForError("请登录");
        }
        Map<String,String> map = new HashMap<>();
        Date time = new Date();
        int replyId = postManageService.insertReplyContent(replyContent,userid,time);
        String postContent = postManageService.getPostByPostId(replyContent.getPostid()).getContent();

        map.put("replyId",Integer.toString(replyId));
        map.put("replyContent",replyContent.getContent());
        map.put("postId",Integer.toString(replyContent.getPostid()));
        map.put("postContent",postContent);
        map.put("time",time.toString());
        map.put("replyerid",Integer.toString(userid));

        return CommonResponse.createForSuccess(map,"回复贴子成功");
    }

    @GetMapping("/posts/{postid}/replies")
    @ResponseBody
    public CommonResponse<List<ReplyContent>> getReplies(@PathVariable int postid){
        if(postManageService.getReplyContentList(postid) != null){
            return CommonResponse.createForSuccess(postManageService.getReplyContentList(postid),"获取所有回复成功");
        }
        return CommonResponse.createForError("没有回复");
    }

    @GetMapping("/sections/{sectionid}/files")
    @ResponseBody
    public CommonResponse<List<Files>> getFileList(@PathVariable int sectionid){
        //只有版主或管理员可以获取某个版块的所有附件列表
        if(isAdmin() || ismoderator(sectionid)){
            return CommonResponse.createForSuccess(sectionService.getFileList(sectionid),"获取附件列表成功");
        }
        return CommonResponse.createForError("获取附件列表失败");
    }

    @PostMapping("/files")
    @ResponseBody
    public CommonResponse<String> uploadFiles(@RequestParam("file") MultipartFile file, HttpServletRequest httpServletRequest) throws IOException {
        System.out.println("uploadFiles");

        if(file.isEmpty()){
            return CommonResponse.createForError("文件为空，上传失败");
        }

        //准备文件夹，获取服务器中upload文件夹的位置
        String parentDir = httpServletRequest.getServletContext().getRealPath("upload");
        //输出文件位置
        System.out.println("\tpath=" + parentDir);
        File parentFile = new File(parentDir);

        if(!parentFile.exists()){
            parentFile.mkdirs();
        }

        String originalFilename = file.getOriginalFilename();
        System.out.println("originalFilename:" + originalFilename);

        // 确定最终保存时使用的文件
        String filename = UUID.randomUUID().toString();
        String suffix = "";
        assert originalFilename != null;
        int beginIndex = originalFilename.lastIndexOf(".");
        if (beginIndex != -1) {
            suffix = originalFilename.substring(beginIndex);
        }

        // 执行保存文件
        File dest = new File(parentFile, filename + suffix);

        //将文件路径插入数据库
        String fileSrc = dest.getPath();
        Files files = new Files();
        files.setFilesrc(fileSrc);
        files.setFileDescription(originalFilename);
        postManageService.insertFile(files);

        file.transferTo(dest);

        return CommonResponse.createForSuccess("上传文件成功");
    }

    /**
     * @param path     想要下载的文件的路径
     * @param response
     * @功能描述 下载文件:
     */
    @GetMapping("/downloadfile")
    public void download(String path, HttpServletResponse response){
        try {
            // path是指想要下载的文件的路径
            File file = new File(path);
            // 获取文件名
            String filename = file.getName();
            System.out.println(filename);
            // 获取文件后缀名
            String ext = filename.substring(filename.lastIndexOf(".") + 1).toLowerCase();
            System.out.println(ext);

            // 将文件写入输入流
            FileInputStream fileInputStream = new FileInputStream(file);
            InputStream fis = new BufferedInputStream(fileInputStream);
            byte[] buffer = new byte[fis.available()];
            fis.read(buffer);
            fis.close();

            // 清空response
            response.reset();
            // 设置response的Header
            response.setCharacterEncoding("UTF-8");
            //Content-Disposition的作用：告知浏览器以何种方式显示响应返回的文件，用浏览器打开还是以附件的形式下载到本地保存
            //attachment表示以附件方式下载   inline表示在线打开   "Content-Disposition: inline; filename=文件名.mp3"
            // filename表示文件的默认名称，因为网络传输只支持URL编码的相关支付，因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));
            // 告知浏览器文件的大小
            response.addHeader("Content-Length", "" + file.length());
            OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
            response.setContentType("application/octet-stream");
            outputStream.write(buffer);
            outputStream.flush();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }



    private Boolean verifyUserid(int userid){
        return userid != TokenUtils.getClaimByToken(httpServletRequest.getHeader("token"),"userid");
    }

    private Boolean isAdmin(){
        return 2 == TokenUtils.getClaimByToken(httpServletRequest.getHeader("token"),"userid");
    }

    //是否为这个版块的版主
    private Boolean ismoderator(int sectionid){
        int userid = TokenUtils.getClaimByToken(httpServletRequest.getHeader("token"),"userid");
        return accountService.getAccount(sectionService.getSectionOwner(sectionid)).getUserid() == userid;
    }


}
